/**
 * create by hp
 * date 2020/3/7 12:30
 * @type {string[]}
 */

import {cleanDist} from "./cleanDist"
import {execDos} from './helper/ExecDos'
import {sshHelper} from './helper/SSHHelper'
import {sshEmitter} from './helper/SSHEmitter'
import {getConf} from "./readConf"
import {execShell} from './helper/ExecShell'
import * as SftpClient from 'ssh2-sftp-client'
import * as compressing from 'compressing'
import {rootPath} from "./rootPath"
import {sleep} from "./sleep"

/**
 * 执行发布流程
 */
export async function publish(evn: string) {
  // 执行清理
  console.log('step1：执行文件清理>>>>>>>>')
  cleanDist(evn)
  console.log('\t执行文件清理完毕<<<<<<<<\n')

  // 执行编译
  console.log('step2：执行编译>>>>>>>>')
  await execDos([`vue-cli-service build --mode ${evn}`], false)
  console.log('\t执行编译成功<<<<<<<<\n')
  // 获取配置
  const confArray: Array<{ name: string, value: string }> = getConf({
    evn
  })

  sshHelper({
    host: getConfByName(confArray, 'VUE_REMOTE_IP'),
    port: 22,
    username: getConfByName(confArray, 'VUE_REMOTE_AC'),
    password: getConfByName(confArray, 'VUE_REMOTE_PW')
  }, evn)

  sshEmitter.on("ready", async (conn, flag: string) => {
    console.info(`${flag}服务器连接就绪\n`)
    const sftp = new SftpClient()
    await sftp.connect({
      host: getConfByName(confArray, 'VUE_REMOTE_IP'),
      port: 22,
      username: getConfByName(confArray, 'VUE_REMOTE_AC'),
      password: getConfByName(confArray, 'VUE_REMOTE_PW')
    })

    const webRoot = getConfByName(confArray, 'VUE_REMOTE_WEB_ROOT')
    const webPath = getConfByName(confArray, 'VUE_REMOTE_WEB_PATH')
    const publishUrl = getConfByName(confArray, 'VUE_PUBLISH_URL')

    try {
      // 执行远程命令，进行文件删除
      console.log('step3：删除远程服务器web文件>>>>>')
      await execShell(conn, [`cd ${webPath}`, `rm -rf ${webRoot}`], false)
      console.log('\t删除远程服务器web文件成功<<<<<<<\n')

      // 执行文件压缩
      console.log('step4：执行编译文件压缩>>>>>>>')
      await compressing.zip.compressDir(`${rootPath}dist-${evn}`, `dist-${evn}.zip`)
      console.log('\t执行编译文件压缩完毕<<<<<<<<\n')

      // sftp上传文件到远程服务器
      console.log('step5：执行上传编译文件到服务器>>>>>>')
      await sftp.put(`${rootPath}dist-${evn}.zip`, `${webPath}dist-${evn}.zip`)
      console.log('\t执行上传编译文件到服务器完成<<<<<<<<<\n')

      console.log('step6:远程服务器执行解压文件>>>>>>>>>>')
      await execShell(conn, [`cd ${webPath}`, `unzip dist-${evn}.zip`], false)
      await sleep(4)
      console.log('\t远程服务器执行解压文件成功<<<<<<<\n')

      console.log('step7：执行远程服务器编译文件重命名，并删除压缩文件>>>>>>')
      await execShell(conn, [`cd ${webPath}`, `rm -rf dist-${evn}.zip`, `mv dist-${evn} ${webRoot}`], false)
      console.log('\t执行远程服务器编译文件重命名，并删除压缩文件成功<<<<<<<\n')
      console.log('step8： 执行删除本地临时文件>>>>>>')
      await execDos([`del ${rootPath}dist-${evn}.zip`], false)
      console.log('\t执行删除本地临时文件成功<<<<<<\n')
    } catch (e) {
      console.error('编译错误中出现错误，请手动清理publish过程中产生的临时文件，避免出错')
      throw e
    } finally {
      conn.end()
      sftp.end()
    }
    console.log(`[${evn}]环境发布成功 ^_^.......`)
    console.log(publishUrl)
  })
}

function getConfByName(confArray: Array<{ name: string, value: string }>, name: String): string {
  for (let confArrayElement of confArray) {
    if (confArrayElement.name === name) return confArrayElement.value
  }
  return null
}

publish(process.env.evnName)
